{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "No module named 'utils'\n"
     ]
    }
   ],
   "source": [
    "try:\n",
    "    import warnings\n",
    "    warnings.filterwarnings('ignore')\n",
    "    import utils\n",
    "except Exception as e:\n",
    "    print(e)\n",
    "    from tensorflow.keras.applications.vgg16 import preprocess_input\n",
    "    def preprocess_img(x):\n",
    "        return preprocess_input(x, mode='tf')\n",
    "    pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Using TensorFlow backend.\n"
     ]
    }
   ],
   "source": [
    "from keras.preprocessing.image import ImageDataGenerator\n",
    "from glob import glob\n",
    "import tensorflow as tf\n",
    "import keras\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "from keras.applications.inception_v3 import InceptionV3\n",
    "from keras.applications.xception import Xception\n",
    "from keras.applications.resnet50 import ResNet50\n",
    "from keras_applications.resnet import ResNet101\n",
    "from keras_applications.resnext import ResNeXt101,ResNeXt50\n",
    "from keras.applications.nasnet import NASNetLarge\n",
    "from keras.applications.inception_resnet_v2 import InceptionResNetV2\n",
    "from keras.models import Model, Sequential, Input\n",
    "from keras.layers import *\n",
    "from keras.optimizers import Adam\n",
    "from keras.callbacks import ModelCheckpoint, EarlyStopping\n",
    "import os\n",
    "import PIL\n",
    "import time\n",
    "\n",
    "os.environ[\"CUDA_VISIBLE_DEVICES\"] = \"0\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "path_data = '../garbage_classify/train_data'\n",
    "batch_size = 32\n",
    "img_width = 224\n",
    "img_height = 224\n",
    "img_size = 224\n",
    "random_seed = 201908\n",
    "path_data_train = '../tmp/data_train/'\n",
    "path_data_valid = '../tmp/data_valid/'\n",
    "labels_file = '../tmp/labels_raw.csv'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.axes._subplots.AxesSubplot at 0x7f1b3319b898>"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAX0AAAEGCAYAAACJnEVTAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAW6UlEQVR4nO3dfZBV9X3H8fdHWJaChidXxwgW7BAE4hNeiSapwTwIaFtiYhJSOyHaDDFBm2SmNthkah4mnclTWzER3RpNMiVBQ4PZVCNgakzaEeESCcqTbJEMS1RWiWhIFNBv/7i/hQvZu3tXdvfend/nNXPnnvM7v3P5njPD5579nXPPUURgZmZ5OK7WBZiZWf9x6JuZZcShb2aWEYe+mVlGHPpmZhkZXOsCunLiiSfG+PHja12GmdmAsm7dumcjoqmzZXUd+uPHj6dYLNa6DDOzAUXSryst8/COmVlGHPpmZhlx6JuZZaSux/TNzI524MAB2traeOmll2pdSs0NHTqUsWPH0tDQUPU6Dn0zG1Da2to44YQTGD9+PJJqXU7NRATPPfccbW1tTJgwoer1qhrekTRS0jJJWyRtlnShpC9K2iBpvaSVkl6f+krSIkmtafm0ss+ZJ2lbes3r8VaaWfZeeuklxowZk3XgA0hizJgxPf6Lp9ox/ZuA+yPiDOBsYDPw1Yg4KyLOAf4L+KfUdzYwMb3mA4tTgaOBG4E3AdOBGyWN6lG1ZmaQfeB3eC37odvQlzQCuAj4FkBE7I+I5yPihbJuw4GOezTPAb4bJauBkZJOAWYCqyJiT0T8FlgFzOpxxWZm9ppVc6Q/AWgH7pT0qKTbJQ0HkPQlSTuBKzl8pH8qsLNs/bbUVqn9CJLmSypKKra3t/d4g8zM+sOiRYuYPHkyV155Za1L6ZFqQn8wMA1YHBHnAvuAhQAR8ZmIGAcsAa7tjYIiojkiChFRaGrq9FfEZmY1d8stt7Bq1SqWLFlS61J6pJrQbwPaIuKRNL+M0pdAuSXAe9P0LmBc2bKxqa1Su5nZgHLNNdewfft2Zs+ezYgRI7j66quZMWMGp59+OosWLTrU793vfjfnnXceU6dOpbm5+VD78ccfz/XXX8/UqVN55zvfyZo1aw6t39LSAsArr7zC9ddfz/nnn89ZZ53Fbbfd1iu1q5rHJUr6BfCRiNgq6XOUxvCbI2JbWn4d8LaIuELSZZSO+i+ldNJ2UURMTydy13H4C+OXwHkRsafSv1soFML33jGzcps3b2by5MkAfP7HG9n0mxe6WaNnprz+ddz4l1O77ddxb7BvfOMbrFy5kgcffJAXX3yRSZMm8fTTT9PQ0MCePXsYPXo0f/jDHzj//PN56KGHDl15dN999zF79mwuv/xy9u3bx7333sumTZuYN28e69evp7m5md27d/PZz36Wl19+mbe85S384Ac/+KPLM8v3RwdJ6yKi0Fnd1V6nfx2wRNIQYDtwFXC7pEnAq8CvgWtS3/soBX4r8PvUl4jYI+mLwNrU7wtdBb6Z2UBx2WWX0djYSGNjIyeddBLPPPMMY8eOZdGiRSxfvhyAnTt3sm3bNsaMGcOQIUOYNat0HcuZZ55JY2MjDQ0NnHnmmezYsQOAlStXsmHDBpYtWwbA3r172bZtW4+uye9MVaEfEeuBo7813luhbwALKiy7A7ijJwWamVVSzRF5f2hsbDw0PWjQIA4ePMjPfvYzHnjgAR5++GGGDRvGjBkzDl1T39DQcOhyy+OOO+7Q+scddxwHDx4ESj++uvnmm5k5c2av1up775iZ9YG9e/cyatQohg0bxpYtW1i9enWP1p85cyaLFy/mwIEDADzxxBPs27fvmOvybRjMzPrArFmzuPXWW5k8eTKTJk3iggsu6NH6H/nIR9ixYwfTpk0jImhqauKee+455rqqOpFbKz6Ra2ZH6+zEZc56eiLXwztmZhlx6JuZZcShb2YDTj0PS/en17IfHPpmNqAMHTqU5557Lvvg77if/tChQ3u0nq/eMbMBZezYsbS1teEbMh5+clZPOPTNbEBpaGg45l+l5szDO2ZmGXHom5llxKFvZpYRh76ZWUYc+mZmGXHom5llxKFvZpYRh76ZWUYc+mZmGXHom5llxKFvZpYRh76ZWUYc+mZmGXHom5llxKFvZpaRqkJf0khJyyRtkbRZ0oWSvprmN0haLmlkWf8bJLVK2ippZln7rNTWKmlhX2yQmZlVVu2R/k3A/RFxBnA2sBlYBbwxIs4CngBuAJA0BZgLTAVmAbdIGiRpEPBNYDYwBfhg6mtmZv2k29CXNAK4CPgWQETsj4jnI2JlRBxM3VYDHc/smgMsjYiXI+JJoBWYnl6tEbE9IvYDS1NfMzPrJ9Uc6U8A2oE7JT0q6XZJw4/qczXwkzR9KrCzbFlbaqvUfgRJ8yUVJRX9DEwzs95VTegPBqYBiyPiXGAfcGg8XtJngIPAkt4oKCKaI6IQEYWmpqbe+EgzM0uqCf02oC0iHknzyyh9CSDpw8BfAFdGRKTlu4BxZeuPTW2V2s3MrJ90G/oR8TSwU9Kk1PQOYJOkWcA/AH8VEb8vW6UFmCupUdIEYCKwBlgLTJQ0QdIQSid7W3pxW8zMrBuDq+x3HbAkhfV24CpKId4IrJIEsDoiromIjZLuBjZRGvZZEBGvAEi6FlgBDALuiIiNvbo1ZmbWJR0elak/hUIhisVircswMxtQJK2LiEJny/yLXDOzjDj0zcwy4tA3M8uIQ9/MLCMOfTOzjDj0zcwy4tA3M8uIQ9/MLCMOfTOzjDj0zcwy4tA3M8uIQ9/MLCMOfTOzjDj0zcwy4tA3M8uIQ9/MLCMOfTOzjDj0zcwy4tA3M8uIQ9/MLCMOfTOzjDj0zcwy4tA3M8uIQ9/MLCNVhb6kkZKWSdoiabOkCyW9T9JGSa9KKhzV/wZJrZK2SppZ1j4rtbVKWtjbG2NmZl0bXGW/m4D7I+IKSUOAYcDzwHuA28o7SpoCzAWmAq8HHpD0hrT4m8C7gDZgraSWiNh07JthZmbV6Db0JY0ALgI+DBAR+4H9lEIfSUevMgdYGhEvA09KagWmp2WtEbE9rbc09XXom5n1k2qGdyYA7cCdkh6VdLuk4V30PxXYWTbfltoqtR9B0nxJRUnF9vb2KsozM7NqVRP6g4FpwOKIOBfYB/TZeHxENEdEISIKTU1NffXPmJllqZrQbwPaIuKRNL+M0pdAJbuAcWXzY1NbpXYzM+sn3YZ+RDwN7JQ0KTW9g67H4VuAuZIaJU0AJgJrgLXAREkT0snguamvmZn1k2qv3rkOWJLCejtwlaTLgZuBJuBeSesjYmZEbJR0N6UvhoPAgoh4BUDStcAKYBBwR0Rs7OXtMTOzLigial1DRYVCIYrFYq3LMDMbUCSti4hCZ8v8i1wzs4w49M3MMuLQNzPLiEPfzCwjDn0zs4w49M3MMuLQNzPLiEPfzCwjDn0zs4w49M3MMuLQNzPLiEPfzCwjDn0zs4w49M3MMuLQNzPLiEPfzCwjDn0zs4w49M3MMuLQNzPLiEPfzCwjDn0zs4w49M3MMuLQNzPLiEPfzCwjVYW+pJGSlknaImmzpAsljZa0StK29D4q9ZWkRZJaJW2QNK3sc+al/tskzeurjTIzs85Ve6R/E3B/RJwBnA1sBhYCP42IicBP0zzAbGBies0HFgNIGg3cCLwJmA7c2PFFYWZm/WNwdx0kjQAuAj4MEBH7gf2S5gAzUrfvAD8DPg3MAb4bEQGsTn8lnJL6roqIPelzVwGzgO9X+re3t+/jA7c9/Fq2y8zMOlHNkf4EoB24U9Kjkm6XNBw4OSKeSn2eBk5O06cCO8vWb0ttldqPIGm+pKKk4oEDB3q2NWZm1qVuj/RTn2nAdRHxiKSbODyUA0BEhKTojYIiohloBigUCnHXRy/sjY81M8vG3ddUXlbNkX4b0BYRj6T5ZZS+BJ5Jwzak991p+S5gXNn6Y1NbpXYzM+sn3YZ+RDwN7JQ0KTW9A9gEtAAdV+DMA36UpluAD6WreC4A9qZhoBXAJZJGpRO4l6Q2MzPrJ9UM7wBcByyRNATYDlxF6Qvjbkl/C/waeH/qex9wKdAK/D71JSL2SPoisDb1+0LHSV0zM+sfKl1kU58KhUIUi8Val2FmNqBIWhcRhc6W+Re5ZmYZceibmWXEoW9mlhGHvplZRhz6ZmYZceibmWXEoW9mlhGHvplZRhz6ZmYZceibmWXEoW9mlhGHvplZRhz6ZmYZceibmWXEoW9mlhGHvplZRhz6ZmYZceibmWXEoW9mlhGHvplZRhz6ZmYZceibmWXEoW9mlhGHvplZRqoKfUk7JD0mab2kYmo7W9LDqf3Hkl5X1v8GSa2StkqaWdY+K7W1SlrY+5tjZmZd6cmR/sURcU5EFNL87cDCiDgTWA5cDyBpCjAXmArMAm6RNEjSIOCbwGxgCvDB1NfMzPrJsQzvvAH4eZpeBbw3Tc8BlkbEyxHxJNAKTE+v1ojYHhH7gaWpr5mZ9ZNqQz+AlZLWSZqf2jZyOLTfB4xL06cCO8vWbUttldqPIGm+pKKkYnt7e5XlmZlZNaoN/bdGxDRKQzMLJF0EXA18XNI64ARgf28UFBHNEVGIiEJTU1NvfKSZmSWDq+kUEbvS+25Jy4HpEfE14BIASW8ALkvdd3H4qB9gbGqji3YzM+sH3R7pSxou6YSOaUpB/7ikk1LbccBngVvTKi3AXEmNkiYAE4E1wFpgoqQJkoZQOtnb0tsbZGZmlVVzpH8ysFxSR//vRcT9kj4haUHq80PgToCI2CjpbmATcBBYEBGvAEi6FlgBDALuiIiNvbo1ZmbWJUVErWuoqFAoRLFYrHUZZmYDiqR1ZZfXH8G/yDUzy4hD38wsIw59M7OMOPTNzDLi0Dczy4hD38wsIw59M7OMOPTNzDLi0Dczy4hD38wsIw59M7OMOPTNzDLi0Dczy4hD38wsIw59M7OMOPTNzDLi0Dczy4hD38wsIw59M7OMOPTNzDLi0Dczy4hD38wsIw59M7OMOPTNzDJSVehL2iHpMUnrJRVT2zmSVne0SZqe2iVpkaRWSRskTSv7nHmStqXXvL7ZJDMzq2RwD/peHBHPls1/Bfh8RPxE0qVpfgYwG5iYXm8CFgNvkjQauBEoAAGsk9QSEb899s0wM7NqHMvwTgCvS9MjgN+k6TnAd6NkNTBS0inATGBVROxJQb8KmHUM/76ZmfVQtUf6AayUFMBtEdEMfBJYIelrlL483pz6ngrsLFu3LbVVaj+CpPnAfIDTTjut+i0xM7NuVXuk/9aImEZp6GaBpIuAjwGfiohxwKeAb/VGQRHRHBGFiCg0NTX1xkeamVlSVehHxK70vhtYDkwH5gE/TF1+kNoAdgHjylYfm9oqtZuZWT/pNvQlDZd0Qsc0cAnwOKUx/Lelbm8HtqXpFuBD6SqeC4C9EfEUsAK4RNIoSaPS56zo1a0xM7MuVTOmfzKwXFJH/+9FxP2SfgfcJGkw8BJpHB64D7gUaAV+D1wFEBF7JH0RWJv6fSEi9vTalpiZWbcUEbWuoaJCoRDFYrHWZZiZDSiS1kVEobNl/kWumVlGHPpmZhlx6JuZZcShb2aWEYe+mVlGHPpmZhlx6JuZZcShb2aWEYe+mVlGHPpmZhlx6JuZZcShb2aWEYe+mVlGHPpmZhlx6JuZZcShb2aWEYe+mVlGHPpmZhlx6JuZZcShb2aWEYe+mVlGHPpmZhlx6JuZZcShb2aWkapCX9IOSY9JWi+pmNruSvPr0/L1Zf1vkNQqaaukmWXts1Jbq6SFvb85ZmbWlcE96HtxRDzbMRMRH+iYlvR1YG+angLMBaYCrwcekPSG1PWbwLuANmCtpJaI2HRsm2BmZtXqSeh3SpKA9wNvT01zgKUR8TLwpKRWYHpa1hoR29N6S1Nfh76ZWT+pdkw/gJWS1kmaf9SyPweeiYhtaf5UYGfZ8rbUVqn9CJLmSypKKra3t1dZnpmZVaPa0H9rREwDZgMLJF1UtuyDwPd7q6CIaI6IQkQUmpqaeutjzcyMKkM/Inal993ActJwjaTBwHuAu8q67wLGlc2PTW2V2s3MrJ90G/qShks6oWMauAR4PC1+J7AlItrKVmkB5kpqlDQBmAisAdYCEyVNkDSE0snelt7bFDMz6041J3JPBpaXztcyGPheRNyfls3lqKGdiNgo6W5KJ2gPAgsi4hUASdcCK4BBwB0RsbFXtsLMzKqiiKh1DRUVCoUoFou1LsPMbECRtC4iCp0t8y9yzcwy4tA3M8uIQ9/MLCMOfTOzjNT1iVxJLwJba11HlU4Enu22V31wrX3DtfYN19pzfxoRnf669ZjvvdPHtlY6A11vJBVda+9zrX3DtfaNgVCrh3fMzDLi0Dczy0i9h35zrQvoAdfaN1xr33CtfaPua63rE7lmZta76v1I38zMepFD38wsI3Ub+gPpIeqdPTi+Xki6Q9JuSY+XtY2WtErStvQ+qpY1dqhQ6+ck7Ur7dr2kS2tZYwdJ4yQ9KGmTpI2SPpHa62rfdlFn3e1XSUMlrZH0q1Tr51P7BEmPpCy4K92avV5r/bakJ8v26zm1rvWPRETdvSjdevn/gNOBIcCvgCm1rquLencAJ9a6jgq1XQRMAx4va/sKsDBNLwS+XOs6u6j1c8Df17q2Tmo9BZiWpk8AngCm1Nu+7aLOutuvgIDj03QD8AhwAXA3MDe13wp8rI5r/TZwRa3r6+pVr0f600kPUY+I/UDHQ9SthyLi58Ceo5rnAN9J098B3t2vRVVQoda6FBFPRcQv0/SLwGZKz3yuq33bRZ11J0p+l2Yb0iuAtwPLUnvN9yl0WWvdq9fQr+oh6nWkqwfH16OTI+KpNP00pQfl1LNrJW1Iwz91MRRVTtJ44FxKR3t1u2+PqhPqcL9KGiRpPbAbWEXpL/7nI+Jg6lI3WXB0rRHRsV+/lPbrv0pqrGGJnarX0B9ounpwfF2L0t+n9XyEshj4M+Ac4Cng67Ut50iSjgf+E/hkRLxQvqye9m0nddblfo2IVyLiHErP0J4OnFHjkio6ulZJbwRuoFTz+cBo4NM1LLFT9Rr6A+oh6lHhwfF17BlJpwCk9901rqeiiHgm/ed6Ffh36mjfSmqgFKRLIuKHqbnu9m1nddbzfgWIiOeBB4ELgZGSOu4TVndZUFbrrDScFhHxMnAndbZfoX5Df8A8RL2bB8fXqxZgXpqeB/yohrV0qSNAk8upk32r0kOjvwVsjoh/KVtUV/u2Up31uF8lNUkamab/BHgXpXMQDwJXpG4136dQsdYtZV/4onTuoeb79Wh1+4vcdAnZv3H4IepfqnFJnZJ0OqWjezj84Pi6qVXS94EZlG75+gxwI3APpSsiTgN+Dbw/Imp+ArVCrTMoDUEEpaukPlo2Zl4zkt4K/AJ4DHg1Nf8jpfHyutm3XdT5Qepsv0o6i9KJ2kGUDkjvjogvpP9jSykNlzwK/E06kq6ZLmr9b6CJ0tU964Fryk741oW6DX0zM+t99Tq8Y2ZmfcChb2aWEYe+mVlGHPpmZhlx6JuZZcShb1ZGUpeX10kaX34X0Co/89uSrui+p1nfc+ibmWXEoW/WCUnHS/qppF+mZyWU3+V1sKQlkjZLWiZpWFrnPEkPpRvvrTjqV69mdcGhb9a5l4DL0430Lga+nn5aDzAJuCUiJgMvAB9P97e5mdK91M8D7gDq5pfZZh0Gd9/FLEsC/jndMfVVSrfz7bhN8s6I+N80/R/A3wH3A28EVqXvhkGU7l5pVlcc+madu5LSPVTOi4gDknYAQ9Oyo+9dEpS+JDZGxIX9V6JZz3l4x6xzI4DdKfAvBv60bNlpkjrC/a+B/wG2Ak0d7ZIaJE3t14rNquDQN+vcEqAg6THgQ8CWsmVbKT0sZzMwClicHut5BfBlSb+idIfFN/dzzWbd8l02zcwy4iN9M7OMOPTNzDLi0Dczy4hD38wsIw59M7OMOPTNzDLi0Dczy8j/A5F85l1ULq6gAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "labels_train = pd.read_csv('../tmp/labels_train.csv')\n",
    "labels_valid = pd.read_csv('../tmp/labels_valid.csv')\n",
    "n_classess = labels_train.label.unique().shape[0]\n",
    "n_classess\n",
    "labels_train.groupby(by='label').count().plot()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "labels_train.label = labels_train.label.apply(lambda x: f'{x:02d}')\n",
    "labels_valid.label = labels_valid.label.apply(lambda x: f'{x:02d}')\n",
    "# labels_train['label_bin'].values = keras.utils.np_utils.to_categorical(\n",
    "#     labels_train.label, n_classess)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found 240000 validated image filenames belonging to 40 classes.\n",
      "Found 2978 validated image filenames belonging to 40 classes.\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.axes._subplots.AxesSubplot at 0x7f1b2f8decc0>"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXcAAAEGCAYAAACevtWaAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAgAElEQVR4nO2dd3hc5ZX/P++MRmXUy0iWLduSu2xswIVQAtgYsIGEkpCEhB8hgSwJyaZuKsluNrspu5tOskDIQiAJCRASIIEUU0wHG9m44SoXNRf13qa8vz9mrjyWp9wp0oxmzud59Hh0587M8ZX0nTPnPef7Kq01giAIQmphSXQAgiAIQvwRcRcEQUhBRNwFQRBSEBF3QRCEFETEXRAEIQXJSHQAAGVlZbq6ujrRYQiCIEwptmzZ0q61dgS6LynEvbq6mrq6ukSHIQiCMKVQSjUEu0/KMoIgCCmIiLsgCEIKIuIuCIKQgiRFzV0QBGE8TqeT5uZmhoeHEx1KwsnOzqaqqgqbzWb6MSLugiAkJc3NzeTn51NdXY1SKtHhJAytNR0dHTQ3N1NTU2P6cVKWEQQhKRkeHqa0tDSthR1AKUVpaWnEn2BE3AVBSFrSXdgNorkOIu5pzONvNdM37Ex0GIIgTAAi7mlKQ8cAn39kO0/vOJboUAQhabnzzjupra3lxhtvTHQoESMLqmlKe/8IAJ2DowmORBCSl7vuuotnn32WqqqqRIcSMZK5pykd/V5R7xmUsowgBOITn/gEhw4d4oorrqCwsJBbbrmF1atXM2fOHO68886x86699lpWrFjBkiVLuPfee8eO5+Xl8aUvfYklS5Zw6aWXsnnz5rHH//nPfwbA7XbzpS99iVWrVrFs2TJ+8YtfxC1+ydzTlM4Br7h3i7gLU4Bv/eVtdh/tjetzLp5ewDffvSTo/ffccw9///vf2bhxIz//+c/ZsGEDGzdupK+vj4ULF3L77bdjs9m4//77KSkpYWhoiFWrVvHe976X0tJSBgYGuOSSS/j+97/Pddddxze+8Q2eeeYZdu/ezc0338zVV1/NfffdR2FhIW+++SYjIyNccMEFXH755RG1PAZDxD1N6TDEfUjKMoJghquuuoqsrCyysrIoLy/nxIkTVFVVceedd/L4448D0NTUxIEDBygtLSUzM5P169cDsHTpUrKysrDZbCxdupQjR44AsGHDBnbs2MFjjz0GQE9PDwcOHBBxF6KnSzJ3YQoRKsOeLLKyssZuW61WXC4XL7zwAs8++yyvv/46drud1atXj/Wj22y2sRZGi8Uy9niLxYLL5QK8A0o/+9nPWLduXdzjlZp7mmKUZXqGRNwFIVp6enooLi7Gbrezd+9e3njjjYgev27dOu6++26cTu/f4f79+xkYGIhLbJK5pykdkrkLQsysX7+ee+65h9raWhYuXMi5554b0eM/9rGPceTIEZYvX47WGofDwRNPPBGX2JTWOi5PFAsrV67UslnH5PLun73CzpYesm0W9v7nFYkORxBOY8+ePdTW1iY6jKQh0PVQSm3RWq8MdH7YsoxS6n6lVKtSaleA+/5FKaWVUmW+75VS6k6lVL1SaodSanmU/w9hgjHKMsNOD8NOd4KjEQQh3pipuT8ArB9/UCk1E7gcaPQ7fAUw3/d1G3B37CEKE0HHwAi5mVZA6u6CkIqEFXet9UtAZ4C7fgx8GfCv61wD/Fp7eQMoUkpVxiVSIW4MjboZdnqoceQCUncXkpdkKBsnA9Fch6i6ZZRS1wAtWuvt4+6aATT5fd/sOxboOW5TStUppera2tqiCUOIko4Br/XAnLI8ALrFgkBIQrKzs+no6Eh7gTf83LOzsyN6XMTdMkopO3AH3pJM1Git7wXuBe+CaizPJUSGUW+vKfNl7lKWEZKQqqoqmpubkeTv5E5MkRBNK+RcoAbY7mvQrwK2KqXOAVqAmX7nVvmOCUmE0QY5x1eWEX8ZIRmx2WxxmdRMVyIuy2itd2qty7XW1Vrraryll+Va6+PAn4EP+7pmzgV6tNbiKZtkdPpMw+Y6fGUZsSAQhJTDTCvk74HXgYVKqWal1K0hTv8rcAioB34JfDIuUQpxpctXY59ZYifDomRBVRBSkLBlGa31B8PcX+13WwOfij0sYSLpGBglw6IoyM6gyG6TmrsgpCDiLZOGdPaPUpybiVKKwhyb1NwFIQURcU9DOgZGKc3NBKDInik1d0FIQUTc05DOgRFKDHHPsUnNXRBSEBH3NKRr0Dkm7oV2EXdBSEVE3NOQjv6Rk2WZnEzxlhGEFETEPc1wuj30DrsoHqu52+gfceF0exIcWWqgtWbTIRmZFxKPiHuaYWyvV+on7iDOkPHijUOdfODeN9jW1J3oUIQ0R8Q9zTCsB0pyvfs5FuaIuMeT1j7v/pnNXUMJjkRId0Tc04yuMXE/2QoJYvsbL4w3yRO9wwmOREh3RNzTDCNzL8072QoJ0CO97nHBGAhr6xtJcCRCuiPinmZ0npa5e8VdMvf4IJm7kCyIuKcZRuZuZOxFOVKWiSe9w97r2CqZu5BgRNzTjM6BEYrsNjKs3h99fnYGSsmGHfFCMnchWRBxTzO6Bk5OpwJYLIZ5mNTc44Eh7pK5C4lGxD3N6Bg4OZ1qUJQjtr/xomfIBUDfsIvBUVeCoxHSGRH3NKNzYPSUzB2g0J4pNfc40TvkxGZVALT2SvYuJA4R9zQjkLhL5h4/eoacYxuPS2lGSCQi7mmEx6NPcYQ0KLJLzT0euNwe+kdczK/IB2RRVUgsIu5pRO+wE7dHj1kPGEjmHh96h7019vnl3o3HJXMXEomIexrRMc40zKDQ7rX99XjEyTAWjE6ZWSV2MjMstErmLiQQEfc0Yvx0qkFRjg2tvR0eQvQY4l6YY6M8P0sydyGhhBV3pdT9SqlWpdQuv2PfV0rtVUrtUEo9rpQq8rvva0qpeqXUPqXUuokKXIicjv4g4m5YEIi/TEz4i3tFQbbU3IWEYiZzfwBYP+7YM8AZWutlwH7gawBKqcXADcAS32PuUkpZ4xatEBNBM3fxl4kLkrkLyURYcddavwR0jju2QWttfIZ/A6jy3b4GeFhrPaK1PgzUA+fEMV4hBroGA4t7oeEvI4uqMSGZu5BMxKPmfgvwN9/tGUCT333NvmOnoZS6TSlVp5Sqa2tri0MYQjg6+kfJzbSSbTv1w9TJzF3KMrHQ6xP3ghwbjvws+oZdDI26ExyVkK7EJO5Kqa8DLuChSB+rtb5Xa71Sa73S4XDEEoZgks6BEUryMk87XiS7McWFniEnWRkWsm1WKgqygZM7MwnCZBO1uCulPgK8C7hRn9wNuAWY6Xdale+YkAR0DIye1uMOJ7fak5p7bPQMOseuZXm+9zqfEAsCIUFEJe5KqfXAl4GrtdaDfnf9GbhBKZWllKoB5gObYw9TiAedA6OU+Eow/mRYLeRnZYi4x0jv8Elxl8xdSDRmWiF/D7wOLFRKNSulbgV+DuQDzyiltiml7gHQWr8NPArsBv4OfEprLUXHJKErSOYOUGi3SStkjPQM+Yu7ZO5CYskId4LW+oMBDt8X4vzvAN+JJSgh/mit6RgYHds7dTxefxnJ3GOhZ8jJNF/GXphj806pSuYuJAiZUE0TBkfdjLg8p7VBGhTlZEorZIz4Z+5KKW+vu2TuQoIQcU8Tgg0wGRTabdIKGSM9Q04Kck6uaXgHmSRzFxKDiHuaYJiGldiDZe42aYWMAbdH0zfsGsvcAd8gk2TuQmIQcU8TugxxD1Fz7x50crKrVYiEvuGT06kG5flZMqUqJAwR9zQhmN2vQVFOJi6PZkAmKqPC33rAoLwgW6ZUhYQh4p4mdA54ywOhau4gFgTR0uNnPWBgDDJJ3V1IBCLuaULHwCiZVgt5WYG7X4tkSjUmAmXuJweZpO4uTD4i7mlCZ793Y2ylVMD7C8VfJiZCibvU3YVEIOKeJnQNjlIcpCQDUOTropHMPToC1tyNskyCOmYGRly43J6EvLaQeETc04SOgdGgi6kguzHFSiBxL7LbyLRaOJGgmvv6n77EzzfWJ+S1hcQj4p4mdA6MBl1MBXGGjJWeISeZVgvZtpN/UkopHPlZtCUgc+8ddtLUOcT2pu5Jf20hORBxTxOMmnswsm1Wsm0WqblHSa9vOnX8mkZFQVZCMveWriEAjnQMhjkzNCMuNyMuaeWcioi4pwEjLjd9I66QZRnw+ctIK2RUeH1lTu9EKs9PzJRqs0/cGzsHccZQd//UQ1v5/CPb4hWWMImIuKcBRqkl1IIqnJxSFSLH3zTMn4qCLFoT0C3T3OXN2N0ePSb00bC1sZtNhzplcnkKIuKeBnT0h55ONSjMsYkzZJT0DrkCint5QTa9wy6GnZNb2mjxE/Qj7QNRPUf34CidA6N0DIzSJr36Uw4R9zQgnCOkgXi6R0+wzD1R7ZDNXUNjb+aHohT3g20nH7f7WG9c4hImDxH3NKDDZz0QbKMOA6+nu9TcoyF4WcY3yDTJi6rN3YOcMaOQ/OyMqDP3g239Y7f3HOuLV2jCJBF2JyZh6nMycw+8xZ6B1Nyjw+PRp+yf6k95QWIy95auIc6sKqJrcJQjHdGJ+6G2AWxWRUluJnuPS+Y+1RBxTwO6BkZRioDi40+h3caIy8Ow0022zTpJ0U19+kZcaH2qaZhBRf7kWxD0j7joGnRSVWynb9jFloauqJ7nUFs/s0tzmV1iZ4+UZaYcUpZJAzoGRim2Z2K1BPaVMSjK8ZZtpNc9MnoDTKcaGFOqk2keZiymzijOoaYsl6M9Q1Et6B5s62dOWS61lQUcbBuY9EVhITZE3NOAcNOpBmMWBFKaiYhA1gMGxpTqZLZDtnR72yCrfOKuNTR1RjbM5HR7aOwcZG55HrWVBbg9mvrW/vAPFJIGEfc0oMOsuOeIp3s0BPJy96d8kqdUjb72quIcqstygcg7Zpo6B3G6tS9zzwekY2aqEVbclVL3K6ValVK7/I6VKKWeUUod8P1b7DuulFJ3KqXqlVI7lFLLJzJ4wRydYUzDDMY27JCyTESEytzBW3efzAXV5q4hMjMslOVmUVPqFfdIO2YO+dog5zjymF2aS47NKnX3KYaZzP0BYP24Y18FntNazwee830PcAUw3/d1G3B3fMIUYqHLdFnGV3OXskxEhBP38oLJ3Uu1pWuIqqIcLBZFod1GSW5mxB0zh9q9JZi5jlysFsXCafki7lOMsOKutX4J6Bx3+BrgQd/tB4Fr/Y7/Wnt5AyhSSlXGK1ghcjweTddghGUZ6XWPiLCZ+yRPqTZ3DTKjOGfs++pS+1gmbpaDrQOU5maOveHXVhaw51if2BBMIaKtuVdorY/5bh8HKny3ZwBNfuc1+46dhlLqNqVUnVKqrq2tLcowhHB0Dznx6PDTqQD2TCs2q5IF1QjpGXKSYVHYMwO3j072lGpL9xBVfuJeU5YXVeY+x5E79v3iynx6hpwc65FdpaYKMS+oau9becRv51rre7XWK7XWKx0OR6xhCEEItzG2P0opCnMypeYeIcZ0arAtDMvH9lKdeGEcGnXT3j9KVbF97FhNmZ0TvSMMjLhMP8+htgHmOvLGvq+tLACQ0swUIlpxP2GUW3z/tvqOtwAz/c6r8h0TEsRJ07DQ06kG4i8TOcGsBwwqfFOqk2H9698GaVBT5hVps9l796DXLMw/c18k4j7liFbc/wzc7Lt9M/Ck3/EP+7pmzgV6/Mo3QgIwaxpmUJRjk5p7hBgbdQSjPH/yMnejDXJGkV/NvcybxR9pN9frbhiGzSk7mbnnZWUwq8QuHjNTiLD2A0qp3wOrgTKlVDPwTeC/gEeVUrcCDcD7faf/FbgSqAcGgY9OQMxCBHQORijudpvUVSOkZ8hJsT349S2227BZ1aRk7id73E+WZaqNdkiTmfshn2HY3PK8U47XVkrHzFQirLhrrT8Y5K61Ac7VwKdiDUqIH52+skxxbmhfGYPCnEzJziKkZ8g5JqCBUEpRnp89KVOqzV1D2KxqbBEXIDcrg4qCLNMdMwd9hmEz/Uo74K27b9h9gsFRF/ZMsaVKdmRCNcXpGBglPyuDrAxzRmBFdpt4y0RIb5iaO3h73SfDX6ale4jpvh53f6pLcyPK3GeX5pJhPVUeaisL0Br2HZc3/6mAiHuK0zkwSkkYH3d/inJs9I+4Ytp3M53QWtM7HHgXJn/K8ydnkKm5a/CUxVSDmrJc01OqhmHYeBaPLaqKuE8FRNxTHLOmYQaGeZhk7+boH3Hh9uiw4l5RkD0pmXtz1xBVRfbTjteU5dIxMBr25+ryGYbNceSddl9VcQ75WRlSd58iiLinOJ0Do5SEWOwbT6HvXBlkMke46VSD8vwseoacEzqlOux009Y3csp0qoFhIBYue2/qGsLp1sx1nJ65K6VYJIuqUwYR9xQn4sw9x8jcpR3SDOEcIQ2MQaaJ3Gj6aPdJN8jx1JSZ65g56LP1DZS5g7fuvvd4Hx6P2BAkOyLuKYzWOvKau3i6R8RJcQ/dPTK2l+oE1t0D9bgbzCqxoxRhO2b8DcMCUVtZQP+Ia+y1hORFxD2F6R9xMer2mLL7NTB2YxJxN0eoXZj8GfOXmcDMvcXI3EtOr7ln26xML8wJm7kfajvVMGw8hg2BeLsnPyLuKYzZjbH9EU/3yDBbc5+czH2QDIuiIj/wz9tMx8zBtlMNw8azsCIfixIbgqmAiHsKY4h7JJl7flYGFgU9shuTKcyK+2RMqTZ3DTGtMPu0/nSDmrJcDrUPhLTtHW8YNp6cTCvVZbmTLu4b97Zy6Y9eZGhU9nE1i4h7CmOIe3EE4m6xKApzbJK5m6RnyInVosjLCl1zH5tSnUB/mZauoYCLqQbVZbn0DbvGfi/GE8gwLBC1lQXsOT654v7Xnceob+1n/wnpsTeLiHsK0xFF5g7eHZmk5m6OniEnBdkZQe1+/fFulD2xmbu/p8x4agwDsSB190CGYYFYXFlAU+cQfcOT9zuypbELQMTdj3DurSLuKUykjpAGkrmbp2co/HSqQUVB1oRl7qMuDyf6hgN2yhgY1r/BOmaCGYaNx9gwe+8k2RB0DoyOxVzva9VMd7TWfObht0KeI+KewnQOjJKVYQm6Q1AwvJ7uUnM3Qzgvd3/K87MnrOZ+rGcIrQP3uBtUFedgtaiQmXsgw7DxTPbGHVsbvFm7zaokc/fxlx3HeHF/6B3sRNxTmM6BUUpzM02VDPwpkszdND1hvNz9qSiYuCnVQFa/47FZLcwszgnq636orZ9ZJfagC7IG0wqyKbLbJk3ctzR2kWFRrFlYzv4Tkrl3D47yH395mzOrCkOeJ+KewnQOjEa0mGogNXfzmHGENJjIKdXmrtN3YAqE0TETiEPtoTtlDJRS1E4rYPckGYhtaehiyYxCllUV0tI9FNF2ganI9/66l65BJ997z7KQ54m4pzAdEVoPGBTm2OgdduKWEfOwRFaWMQaZ4l93b+kawqJgWmF2yPOqy3Jp6Di9HdLl9tDQMRDUdmA8tZUF7DveO+G/I6MuD9ubulkxq5j5Fd5a/4E0rru/frCDR+qa+NiFNSyeXhDyXBH3FKZzYCTiThnw1ty1ZlK7IaYiWuuIxP3kINNEZO5DVBbmYAtTUqkpy2Vw1H3apGwow7BA1FbmM+z0mPaIj5bdx3oZcXlYMbuYBT5xT9e6+7DTzdcf38nMkhw+t3ZB2PNF3FOYzv7RiKZTDSbbX+Yrj+3g20/tnpTXiieDo25Tdr8GRuY+EVOqzV1DITtlDAwDsfEdM0anTCSZO8BeE6WZH27Yxy0PvGnqecezxbeYurK6mFkldjIzLGnbMXPXCwc51D7Ad65dSo6JJgkR9xRl2OlmYNRNaQSmYQZj/jKTsKi6q6WHR+qaeOC1IxzrmVpmVGanUw2K7ZnYrGpC/GVaukMPMBkE20/1YFtow7DxzCvPw2pRYRdV/1DXxM+er+f5va2mNwvxZ2tDFzOKcqgoyMZqUcx15KVl5n7gRB93v1DPtWdN56IFDlOPEXFPUbp8rYyhNm4Oxpi/zCS0Q9794kFyM614tOY3rzdM+OvFk0jF3WJROPLivyOT0+3hWI85cZ9elEOm1XKa0IYzDBtPts3KXEdoG4K3Grv4+uO7WDrD29Xx3N5WU89toLWmrqGTFbOLx44tqMjjQJp1zHg8mq/9aSe5WRl8412LTT9OxD1F6eiPboAJ/D3dQ2fuHo/mpvs28ds3ohPlQ239/HXnMT58fjWXL57G7zY3TinvkEjFHbwdM/HuljneM4xHE3CTjvFYLYrZpfbTOmbCGYYForayIKi4n+gd5uO/2UJFYRa/vuUcFlTk8dyeExE9f0v3ECd6R1hZ7S/u+bR0D9GfRh0zv3+zkbqGLr5+ZS1leebLrDGJu1Lq80qpt5VSu5RSv1dKZSulapRSm5RS9UqpR5RSkauLEDNjpmHRlGVM7sb0xqEOXj7Qzvf+uieqDpBfvHiITKuFWy6o4ZZ31tA96OTxt1oifp5EYXajDn8mYi9VMz3u/lQHcIc81DYQ1nZgPLWVBRztGT7tE96w083Hf7OF/hEXv/zwSopzM1lbW8Hmw530RrBIb9Tbl886Ke7zfdOzB9KkNNPaO8x//W0v580p5foVVRE9NmpxV0rNAD4DrNRanwFYgRuA/wZ+rLWeB3QBt0b7GkL0RGs9AFCQ7TXBCifuf9jSTG6mlVG3hx/+Y39Er3GsZ4g/vdXMB1bNxJGfxarqYs6YUcD9rx4O6VqYTESTuU/EXqpme9wNaspyaegcHGtjNAzD5pZHnrnDqRtma635+uO72NbUzY/efyaLpnnPWbuoHJdH81KYqUp/tjZ0Yc+0smha/tgxo2MmXUoz3/rLbkZcHr77nqURDyPGWpbJAHKUUhmAHTgGXAI85rv/QeDaGF9DiIJo7H4NMqwW8rMz6A6x1V7vsJO/7TrGNWfP4CPnV/PoliZ2tfSYfo1fvnQYj4Z/unAO4B2MueWCGupb+3n5QHvEMSeC3igy94qCLLoH4zul2tw1hFJQWWhe3EddnrFt+cwaho3H8JjxL8386tUj/HFrM59dO5/1Z1SOHT97VjEluZk8t8d83X1LYxdnzSw6ZWJ2ZomdrAxLWiyqPrv7BE/vPMZnLpk31uUUCVGLu9a6BfgB0IhX1HuALUC31tooiDUDMwI9Xil1m1KqTilV19Zm/t082XmrsStsrXoy6BwYxWpRFGSbFx5/vP4ywf8fT20/xrDTw/tXzuSfL5lPsT2T/3xqt6msu3NglN9vbuSas6Yz02/XoKuWVeLIz+L+Vw9HFfNk0zPkRCmvB75ZyvPjP6Xa0j1ERX42mRnm/pzHd8yYNQwbT3l+NmV5mWPi/sqBdr7z1z1cvriCz66df8q5Voti9UIHG/e14nJ7wj73wIiLPcf6WOm3mGo8z1xH3oQNMp3oHaa+NfFvHP0jLv7tyV0sqMjjtovmRvUcsZRlioFrgBpgOpALrDf7eK31vVrrlVrrlQ6HudaeZOdYzxDvufs1PnjvGwkX+I6BUYrtNiyWyD7KGRTlZIZshfzDlibml+dxZlUhhTk2Pn/ZAjYd7uQfb4dfNHvgtSMMOd3cfvGpv7RZGVZuOnc2L+xrmxK9zF6738iucXlB/KdUm7sGTS2mGoxtlu2rux9qN2cYFgjD272hY4BP/W4rcx25/OgDZwW8JmsXVdA96OStpu6wz7u9qRu3R7N8nLiD0TEzMQJ826/ruPrnr3I4irbNePK7TQ0c7Rnmu9ctNf2mPR7zKcfpXAoc1lq3ASil/gRcABQppTJ82XsVMCVWyDoHRrnt13V8/31nRvURCODlA+1oDXuP9/KRX23mt7e+g9wIsrpweDyauoYuntzWwiv17bjcwbPkzoFRZpZE/sdqUJhjC9oKWd/ax1uN3dxx5aKxOuAHV83kN68f4bt/3cOaRQ6yMgIPWfSPuHjg1cNcvrhibJzcnw+9YxY/31jPA68d5tvXLo06/skgkulUAyNzj+eUanPX0CntguGoKMgix2Yd65g52GrOMCwQtZUFPPDaEW779RYAfvnhlUE3LrloQRk2q+LZPSdYVV0S8nmNxdSzZ53+/5pfkc8T247SN+wkP8pPpoHY2dzD9mZvafFzD7/FY7efH3bidyLweDS/29TIqupiVoa5TqGIJfJG4FyllF15/8LXAruBjcD1vnNuBp6M4TUmjV0tPdQ1dPFEDN0aLx9ox5GfxV03LmdHcw//9Ou6mGurWmt2H+3le3/bwzv/+3ne/4vX+ePWZhZW5HPe3NKgX1ctq+TTl8wP/wJBKLQHd4b8w5ZmrBbFtWefrLhlWC3867sW09g5yIOvHQn6vL/b1EDvsItPrpkX8P6yvCyuPWs6f9zSMil99rEQjbhXGJl7nDpmXG4Px3uGTS+mgnd9w79jxqxhWCBqK/MZdXk40NrH/35oObNLgydG+dk23lFTaqruvqWxiwUVeQGv74IJ8pj53eYGcmxW/ue9y9je3MNPnz0Q1+c3y2sHOzjSMciN75gd0/NEnVZqrTcppR4DtgIu4C3gXuBp4GGl1Ld9x+6LKcJJwqiBvrC/jc9fFt63YTwej+bV+nZWL3Cw/oxKvn+9my88up1PPbSVe25aEXEG0NgxyJ+3t/DktqMcaO3HalFcNL+ML69fxGWLK+L6iSAQRTmBa+4ut4c/bW1hzULHWBZqcOF8B5csKudnz9XznuVVp/XkDjvd/PLlw1wwr5SzZhYFfe2PXlDDo3XNPPxmE5+4OLp642QQjbgX2zPJsChOxKnmfqJvBJdHM6PIXBukQU2ZnT3H+sYMwy6trYjq9ZfPKibDorjjylreOb8s7PmXLCrnP57aTUPHQNA3Ao9Hs7Whi6uWTQ94/4KKk+2QywNk9tHQO+zkyW1HufrM6bx/1UzqGjr53xfquXB+Ge+YUxqX1zDLQ5saKLbbWH/GtJieJ6bPHFrrb2qtF2mtz9Ba36S1HtFaH9Jan6O1nqe1fp/WeuL2FYsjbf3eMHc0dwfdYzIUu4/10jkwOvYL/p7lVfzntWfw3N5WPv/INtPueW8e6eSGe1/nou9v5Acb9nsXKq89g813rOVXHz2Ha8+eMeHCDt4F1e4h52kLpJjgwcwAACAASURBVC8daKOtb4TrV8wM+Lg7rqxlyOnmR8+c3hr5x63NtPWN8KnVgbN2g9rKAs6fW8qDrx3BaWLxLVFEI+4Wi6I8jtvtNXdG1gZpUFOWS2PnIEc6BnC6dcQDTAazS3PZ8e+Xc8s7a0ydb7yJhMre69v66R12BS01VRUbHTPxy9yffKuFwVE3N547C4BvvnsJs0vsfOHR7ZO6fnaid5gNu0/wvpUzybZFtsnOeGRC1YeRuWsNLx+IvHvHaN9757yT2ctN587ma1cs4qkdx7jjTzvxhBD4t4/28NFfbeZ997zOobYBvrx+Ia98ZQ2PfuI8bjp3NqURTKbFg6KcTNwefdok4B/qminJzeSSReUBHzevPI+bzpvNw5sb2eu3ibLL7eEXLx7izJlFnDc3fCZ0ywU1HOsZ5h9vH4/tPzKB9EawUYc/joL4bZTd0m0MMEUm7tWlubg9mhf2eX/Xoy3LANgzzScbs0rtzC/P47m9wRfejXp7MHG3WhTzyuPXMaO15rdvNLJ0RiHLqryfKHOzMvjJDWdzvHeYbzyxa9JmLx59swm3R/PBc2bF/Fwi7j7a+kaYWZJDSW7m2C98JLxS38aiafljGzIYfPziuXzmknk8UtfEfz59eqvg4fYBPv37t7jqzlfY2tjNV69YxItfWsMnV88zPXE4ERj+Mv5ZS+fAKM/uOcG1Z80IuYL/2bXzyc+28e2n9oz9f5/eeYzGzkE+uXquqWGMSxaVM7vUzv2vJGdbZKR2v/7MKrGz51gvI67Ye92N6dTpJhwh/TEydSODNmsYFg8uqS1n06HOoJbSWxq6KM3NpLo0+O//gor8uHXMbGnoYt+JPm58x6mCetbMIj5/6Xz+sv0oT2yb+L4Qt0fz+82NvHNeWdRNHf4kvbhrrfncw29NeAbX1jdCRX42F84v46X9bSGz7PEMjbp583DXKVm7P5+/bAG3XFDDr149wo995YrjPcN87U87ufRHL/Ls7hP885p5vPTlNXzi4rmm7DwnGsNfxn9K9cltLTjdmvetDD0GXWTP5POXzueV+nae39uKx6O5a+NB5pfncZnJ2q7Fovjo+dVsbezmrcau6P8jE8SQ043Tbd7u15/rV1TR3j/K0zuOxRxHc9cgjvysiD/CG73ubx7ppCQCw7B4cGlthW9aNfCw2paGLpbPLg6ZBMyvyONYz3BEdgbBeGhTI/lZGbz7zNNr/Levnseq6mL+9Ym3aeoMvD1hvHhhXytHe4ZPe5OJlqQX95buIZ7YdpT7Xp7YDK6tfwRHfharFzroGBhlZwTTlpuPdDLq9gRdUFJK8a/vquWGVTO58/l6bn3gTS7+/kYe29LETefO5qUvr+GL6xZGJRQThfHH7p+5P1rXzBkzCsbGzkNx47mzmevI5TtP72HD7uPsO9HH7avnRtQTfv3KmeRnZfCrV49EHH8g9p/oi0u2DNA75C1XRfMzu2h+GfPK87jvlditFsxa/Y6nJDeT/OwMXB7zG3TEi7NnFlFktwU0EuvoH+Fw+0DY1s4F5fGxIegcGOXpnce4bnngtSyrRfHjD5yFAj73yDZTA1jR8tCmRhz5WVy6OLrF7fEkvbgb9bc3Gzpp75+4tdl2n7hfNN+BUoTdWdyfVw60kWm18I6a4LVkpRTfuW4pV585nY37WnnXsuk8/y+r+ferl+DIn9x6uhnGb9ixq6WHPcd6eV+QhdTx2KwWvnHVYg61D/CFR7czoygnYGYUirysDD6waiZ/3XksZq/3vcd7WfeTl/jqH3fG9DwG0fjKGCil+OgF1bx9tJc3j8T2qcTsJh2BYpjj++gfqe1ArGRYLaxZWM7Gfa2nNRpsbfQOOIUV9zGPmdhKM3/c0syoy8OHQmTLVcV2vn3dGWxp6OJ/Nx6M6fWC0dw1yMZ9rdywambceuunhLhblHeh89ndkVmGmmXE5aZ70IkjL4vSvCyWzSjkhX3mPTBePtDOyurisOUUq0Xx0xvO4s2vX8oP33/mKaP3ycZYWcbnL/PYlmYyrRauOcu8QK9e6OCiBQ4GR9184uI5Uf3S3nx+dVy83n+0YT9aw+NvtbDNxIRkOGIRd4D3nF1FYY4tpjUFj0dztHso6rWZap+4R2oYFg/W1pbTNeg8reS2paELm1WNecAHo6o4h2xbbB0zHo/md5sbWTm7eMzgLBjXnDWD686ewZ3PHxhLOOPJw5ubUMANcVhINZgS4n7unFKqinMmrO5ueJ+X+TLoixeWs62p29QQTWvfMHuP93HhfHMWCkqpSe98iYYCv5r7iMvNE9tauGxJRUS1WaUU377mDD5yfjXvW2ku4x/PzBJ7zF7vO5q72bD7BLddNIeyvCzTHjihOGn3G11bak6mlQ+9YxYbdh+Pupbb2jeC062jKsvAybr7ZGfuABctcJBhUTw7riVya0MXZ8woDLuGYBnrmIk+c3/9UAeH2wfG2h/D8a1rllBZmM3nHnkrrvsLO90eHn6ziTULy6P6FBaMpBZ3r3lQLytnF7NuyTRere+YkE2bjTZIh090Vy904NHwkgl3wlfrvedcaGKAYyqRbbOSY7PSM+TkuT2tdA86eV+EftLgbX3796uXxNSze+uFXq/3/3v5UFSP984L2Pj0JfP40roFbGno4qkYFzNjzdwBPnzebCxKhZzoDYVh9RuJr4w/Z84sxGZVLJ4efg0l3hRk2zinpuSUuvuoy8P25m5WmBxMWlCeH1PN/aFNDRTZbVzh514ZioJsGz/5wFk0dQ7x2zcao37d8Tyz+wTt/SOm32TMktTivr2pG4+G5T5xH3V7ompTDMeYuPsy9zOrvAs+ZkozL+9vpyQ3k8UmFhmnGkV2r7/MH+qamFaQbfrTSbxZVV3CVcsq+dnG+jEHQ7NsPtzJS/vbuH31XPKzbVy/YiaLKwv4r7/tjckaIh7iXlmYw5VLK3nkzaaodhYy2iCjMfwCWLOwnE13XBpxG2W8WFtbwYHWfho7vG9Sbx/tYcTlMe2TM78in+O9w1ENGbX2DrPh7RO8b0VVRInHyuoSllUV8vc4VhEe2tTAjKIcLl4QeHYkWpJa3OsaulDKax60YnYxpbmZE1KaMaZTDXG3WhQXznfw0v72kC2RWmteqW/ngnllUbsvJjOFOTb2nejnxf1tvGf5DKwJ/D9+892LycqwcMfjO02XVLTW/GDDPhz5Wdx0bjXg/dl+4121tHQPRf1JAE6Ke6zGVbe8s4a+EReP1TVF/FhjgClS6wEDpVRUm7nEi7W+QThjoCnc8NJ4DBuCaCx6H61rwhXlsNC6JdPY3tTN8Z7YB9EOtfXzan0HHzxnZtz/vpJa3Lc0dLGgPJ/CHBtWi+KyxRW8sK8tbu1sBkbm7r8l3eoFDtr7R9gdYgPg/Sf6ae0b4cIg/e1TnSK7bezTU6RbfMWb8vxsvnZFLW8c6uQPW5pNPeaV+nY2H+7k05fMO2Wx+/y5ZaxbUsFdLxyM2sCrd8hJfnZGzH+QZ80sYvmsIn712pGIZivAW5Ypzc1MirmIaKguy2WuI3dskGprYxczS3JOGwQMhtExE+miqndYqIkL5pUyJ4rJ3HVLvK2KG3bHnmj+fnMjGRbF+6NckwpF0oq7x6PZ2th1ip/zuiXT6B9x8Vp9R1xfq61vhCK77RSb2osWeEsQoUozhk2BGcOkqUhRjvfNbuXs4qj+COLNDatmsqq6mO88vSdsW6w3a9/PjKIcPrDq9D+cr11Ri9Pt4fv/2BdVLNFOpwbilnfW0NAxyPN7zXdogbcsE+1iarKwtraCTYe9a2l1R7pM19sBZhTlkGOzRrwr04v7W2npHoradXFeeT5zHLlsMLF3QSiGnW7+sKWZy5dUmH5Di4SkFff6tn76xpkHnT+vlLysjLiXZtr7R8YWUw0c+VksnVEYssb/8oF25jpyE1aznGiMXvdwE6mThcWi+N57ljI46uLbT+0Oee6ze1rZ3tTNZ9bOC+gtX12Wy0cvqOGxrc0RbQ9oEE9xX79kGtMLsyPegaqlK/o2yGRh7aJynG7v2H1r30hEvvRjHTMRZu4PveEdFroshmGhdUum8cahjpC7lYXjb7uO0T3ojNnaNxhJK+51vuEO/222sjKsrF7o4JndJ0y7LJqhrW8k4CDRxQscbG3sCvgDHHa62XS4I2GLjJNBVXEOBdkZQa1XE8G88nw+uXoeT2w7GnTQzOPR/HDDPqpL7bx3efA3pn++ZB4l9kz+I4rWyHiKe4bVwofPr+a1gx2n7EcaCo9H09w9FHWnTLKwYnYxhTk27nrhoO/7yDanmF8RWTtkc9cgz+9r5QMrYxsWWrdkGi6PDmmAFo6H3mikpiyX8ybIUjhpxd0wD5o9zjxo3ZJpdAyMxnWQwLAeGI/REvlK/ektkVsbuhh2eoL6yaQC/3TRHJ7/4uqgO+skik+umcscRy5ff3wng6Ond5k8vfMYe4/38fnLFoTcXagg27s94ObDnfx9V2SfBuMp7uAtOeXYrPzKZPbe3j/CqMsz5csyGVYLqxc66B50kptpZeG003fnCsWCinxO9I6Y7ph55E3vwvUN58RW4142o5BpBdlRVxH2Hu+lrqGLD50za8KaMZJW3I16+3jzoNULHWRaLWyIY2mmrW/ktI0lwLvYVZCdEbDu/nJ9OxkWxbkm7GunKlkZ1oDXJdFkZVj53nVLae4aOm23HJfbw4+f3c/CinzebeITxw2rZrKwIp/v/m1PRK2R8Rb3Insm710xgye2HTVls9E81ikztcUdvHV38HbFRbpA7b9xRzj8h4ViLWdZLIrLl1Tw4v62qIbrfrepkcwMC++dwEaFpBT3UOZB+dk2zp9Xyj92H4+Lx/LAiIvBUXfAzD3DauHCBQ5e3N922mu9fKCN5bOKky6rTRfeMaeUG1bN5P9eOXxKzfyJbUc51DbA5y9bYCojyrBa+Ma7amnqHOKBCIaJ4i3uAB85v4ZRl4ffbQo/IGP0uE/1mjt4y585Nqspn//xzC833zHz8JtNtPWN8P/iNCy0bsk0hp0eXopw/4eeQSd/2trCVUsrJ7QVNSnF3Si5rAyyuLJuyTSaOofYcyx2P+fx06njWb3AQWvfqS2RnQOjvH20N2W7ZKYKX7uilmJ7Jnc8vhO3RzPq8vCTZ/ezdEbhWLuaGS6c72DtonJ+/nz92O9DKIadbkZdnqg26gjFvPI8Vi908Js3GoK2+2qt2dXSw5O+vX6nes0dvPMUz3/xYv7pwjkRP9Zsx8yJ3mH+5297uWBeKWsWxmdY6JyaEgpzbBGXZn79+hH6R1x87EJzu1dFS3KKe6PXPOiMIOZBl9ZWoBRx6ZoZP8A0novHWiJPvju/Wt+O1qlnOTDVKLTb+Oa7F7OjuYcHXzvCo3VNNHcN8S+XLzC1IYg/d1xVy3CQ7QHHE4/p1GDcckENbX0jp3m9H24f4KfPHmDtj17kXT97hZcOtHH9iqqU+eRYWZgTcgOYYFgsytSi6rf+8jajbg/fuXZpxL8bwbBZLaxdVM5ze1pNbwc5NOrmV68dYc1CB0umhzZHi5WkFPdw5kGO/CxWzi6Oj7j3hRb38oJsFlcWnNKZ8fKBNgqyM8a25BISx7uWVbJmoYMfbNjHT587wMrZxWNvyJEw1+HdHvCRNxvDTh5OpLhf6Of13to7zH2vHOaan7/Cmh+8wE+e248jL4vvvWcpb379Un7wvjPj/vpTkflhPGae2X2Cv+48zmfWzh9zwowXly+ZRs+Qk82HO02d//CbjXQOjPLJNaH3EY4HSSfuIy4325t7wg4zrFsyjb3H+8Z8KaIlnLiDdxF3S0MXvcPeDaNfOdDO+XPLEjqOL3hRSvEf15yB1t6f5RfXLYw6M/t/587Go739x6HonUBxV0pxywU1vH20l3d87zn+86nduDyaO65cxKtfuYRHPn4eHzxn1qTunJTsLKjIo7VvJGDLcv+Ii397chcLK/K57aLIyz7huHiBg2ybxVSiOerycO9LhzinuoRV1ZG1fEZDTOKulCpSSj2mlNqrlNqjlDpPKVWilHpGKXXA96/5qQTg7aO9jLo8rKwOL+4Qe2mmvX8Eq0VRHOKPZfXCctwezasH2jnUPsDRnmEuXCAlmWRhZomdH77/TD59yTzOjaFneK4jj0XT8sNufzeRmTvAe5bP4Oozp/PpNfN49gsX8fRnLuS2i+am7LBcrIzZEAQozfzgH/s43jvM9967NG6bYPiTk2nlovkONrx9Iqx9xBPbWjjWM8zta+bGPY5AxPq//Snwd631IuBMYA/wVeA5rfV84Dnf96bZ6ltMXR4mc59ZYqe2siBmcW/rG6E0NzNkFr58VhH52Rm8sK+Nl33lmQvnpe7w0lTkyqWV/MvlC2N+nquWVlLX0BVy56eTXu4TI+7ZNit3fvBsvnD5QuaVR9b3nY7M97VDjl9U3dbUzYOvH+Gmc2eH1ZNYWLdkGsd7h9kRYtLZ7dHc8+JBFlcWsDqKsmE0RC3uSqlC4CLgPgCt9ajWuhu4BnjQd9qDwLWRPO+WBvPmQeuWVLClsctUh0MwgvW4+5NhtXDh/DJe3N/GywfamVViZ1aIndmFqcuVy7ze3n/bGTxpmOjMXYiM6YU52DOtp9TdnW4PX/vTTirys/nSutjf9EOxtrYcq0WFTDT/8fZxDrUN8Mk1c+O2oBuOWDL3GqAN+JVS6i2l1P8ppXKBCq218bn2OBCwJ00pdZtSqk4pVdfW5s2GtdbUNZg3D1q3ZBpaexdMoiXYdOp4Vi8o53jvMC/sb5MumRRmriOP2soCnt4ZvDQzlrlnp0anylTHYlHML887JXO/75XD7DnWy7euWRKzLXM4iuyZnDunJKi4a62564V6aspyTW8MEg9iEfcMYDlwt9b6bGCAcSUY7Z38CViI0lrfq7VeqbVe6XB4P6Y0dw3R1jfCCpOLDYum5TOrxB5TaSaYr8x4DJdIt0eLuKc4Vy2dxpaGLo52By7N9Aw5ycvKCGltIEwu8yvyOdDqzdwbOgb4ybP7WbekYmxtbqJZt2Qah9oGAnrLv3SgnV0tvXzi4jmT2oQRy29nM9Cstd7k+/4xvGJ/QilVCeD717SP6ZhZv8nMXSnFuiUVvHawnd4ott/zeLTXEdKEuE8rzGbRtHwsCs6bK+Keyly51FeaCeI3MxHTqUJsLKjIo61vhK6BUb7xxC4yLBa+dfUZk/b6ly82GjxOryLctbGeaQXZXHf25LqrRi3uWuvjQJNSyihorQV2A38GbvYduxl40uxzbmnoitg8aN2SaTjdmo0RemGD94/U6dZBp1PHc/vquXz84rnyh53izHHksbiygKd3HA14f++Qc8IWU4XomO/rmPn+hn28fKCdL69fyLTC+HukB2NaYTZnziw6zfNqS0Mnmw538rELa6Ia0oqFWF/t08BDSqkdwFnAd4H/Ai5TSh0ALvV9b4q6hq6IzYOWzyqmLC8rKuP8cNOp47nmrBl8Zf2iiF9HmHpctaySrY3dAUsz3sxd6u3JhNEO+btNjZw9q2jCPNJDsW5JBdube07ptLpr40GK7baotvOLlZjEXWu9zVc3X6a1vlZr3aW17tBar9Vaz9daX6q1NjW61TfsZN/x3ojM+sG7mOLdfq814g2P200MMAnpiVGa+WuAhVUpyyQf0wuzyc20kuHb0CURA4ZGfd9INPce7+W5va185PwachNgE5E0K0Lbm3rwaPOb4/rzznllDIy6qW+NbEeWSDN3IX2oKctlyfTAXTMi7smHUoqbz6/mG1fVsmhaQUJimOvIY64jd6zB4+4XDpKbaeXm8yf/UwQkkbhvaehCKThrVuR+LTU+v4gjHQMRPc6M9YCQvly5tJK3GrtpGVeaEXFPTr68fhEfuWBinRbDsW7JNDYd7mR7Uzd/2X6UG8+dnTCriKQR97qGThZW5FMQRU9qdZl3oOhwW+TinplhIT9FnPWE+HKV0TXjl72PuNwMOz0i7kJA1i2Zhtujuf23W8iwWLj1nYl7s0kacd/W2B1VSQbAnpnBtIJsDkeRuTvysiZtYkyYWlSX5XLGjAKe8vOakelUIRTLqgqpLMzmaM8w16+sosLEpP1EkRTiPux00zfiilrcwZu9H2mPUNxN9rgL6cuVSyvZ1tRNc5fXfbR3gn1lhKmNUor1Z0zDalF8fAJcKCMhKcR90LcHYSziXlOWx+FIxd3kdKqQvpwszXgXySRzF8LxhcsW8OSnLmB2aXy94yMlKcR9YNRFWV4Ws0qiN+OqKbPTNegM6OkcDBF3IRyzS3NZOqOQp3x1dxF3IRz52bagu8hNJkkh7oMjblbMLoqp9l3te5c0W3d3uT10Do6ank4V0pcrl1ayvambps5BeodcgIi7kPwkhbiPuj0xlWQA5jh84t5urte9c2AUraUNUgjPWGlm17EJ93IXhHiRFOIOsdXbwbt5h0XB4XZz2+61So+7YJJZpXaWzijk6R3HpCwjTBmSQtwVxFyjysqwMr0ox3THjDGdGm6jDkEAr9fM9uYe3j7agz3TOiFbtglCPEmK39AZxTlkZVhjfp6aslzTHTPGdGq5ZO6CCYzSzLN7WiVrF6YESSHuoTanjoSaslyOtA/g3SMkNIa4S+YumGFmiZ1lVYW4PVrEXZgSJIW4x4vq0lz6Rlx0DIyGPbetb4T8rAxyMmP/xCCkB0b2LoupwlQgpcS9ZqxjJnxpRqZThUgxbIAlcxemAqkl7qURiHvfCGUi7kIEzCyxc/2KKi6SPXSFKUBK2SFWFeeQYVGmOmba+0eorUyM77MwdfnB+85MdAiCYIqUytwzrBZmldhNZ+4ynSoIQqqSUuIOXpvWcOI+7HTTN+ySmrsgCClL6ol7aS4NHYN4PMHbIcd2YJLMXRCEFCXlxL3GkcuQ082JvuGg58jeqYIgpDoxi7tSyqqUeksp9ZTv+xql1CalVL1S6hGl1KRuIGimY0b2ThUEIdWJR+b+WWCP3/f/DfxYaz0P6AJujcNrmMbYT/VICAMxEXdBEFKdmMRdKVUFXAX8n+97BVwCPOY75UHg2lheI1KmF+aQmWEJaf3b1jeCUlCSm5hdyQVBECaaWDP3nwBfBjy+70uBbq21y/d9MzAj0AOVUrcppeqUUnVtbW0xhnESi0VRXWoPaf3b1j9CiT1TnP0EQUhZolY3pdS7gFat9ZZoHq+1vldrvVJrvdLhcEQbRkBqynI5EmJHpnbZXk8QhBQnlgnVC4CrlVJXAtlAAfBToEgpleHL3quAltjDjIzqslw27m3D7dFYLadv3Se+MoIgpDpRZ+5a669prau01tXADcDzWusbgY3A9b7TbgaejDnKCKkpzWXU7eFo91DA+2U6VRCEVGciis5fAb6glKrHW4O/bwJeIyQ1ZcHbIbXWYhomCELKExfjMK31C8ALvtuHgHPi8bzR4i/uFy04tZ7fN+JixOWRzF0QhJQmJdtFHPlZ5GZaA2bu0uMuCEI6kJLirpSiOkjHjIi7IAjpQEqKOwR3hxRxFwQhHUhZca8pzaW5awin23PK8fZ+cYQUBCH1SV1xL8vF7dE0dZ46qdrWN4LNqmQfTEEQUpqUFffqIO2QbX0jlOVlYQkw3CQIgpAqpKy4B+t1b+v3irsgCEIqk7LiXmy3UZhjO61jpk18ZQRBSANSVtyNdshAZRlZTBUEIdVJWXEHqCm1n7Jph9uj6RgYlcxdEISUJ7XFvSyPoz1DDDvdAHQNjuL2aBF3QRBSnpQW9+oyO1pDQ4c3e5cBJkEQ0oWUFvfxHTNjA0wi7oIgpDgpLe5Gr7vRMTOWucuCqiAIKU5Ki3tBto2yvEwOt40Td8ncBUFIcVJa3AGqS3M57Je559is5GbFxcZeEAQhaUl5ca8py+WIr+Yue6cKgpAupLy4V5fl0to3Qv+IS6ZTBUFIG1Je3I2OmSPtAzKdKghC2pA+4t4xIGUZQRDShpQX9+pSr7jvP9FP96BTxF0QhLQganFXSs1USm1USu1WSr2tlPqs73iJUuoZpdQB37/F8Qs3cnIyrUwryKbuSCcgbZCCIKQHsWTuLuBftNaLgXOBTymlFgNfBZ7TWs8HnvN9n1BqynJ5q7EbkAEmQRDSg6jFXWt9TGu91Xe7D9gDzACuAR70nfYgcG2sQcZKdVkuQz7zsDLJ3AVBSAPiUnNXSlUDZwObgAqt9THfXceBiiCPuU0pVaeUqmtra4tHGEGpKbOP3ZayjCAI6UDM4q6UygP+CHxOa93rf5/WWgM60OO01vdqrVdqrVc6HI5YwwhJTVne2O2yvMwJfS1BEIRkICZxV0rZ8Ar7Q1rrP/kOn1BKVfrurwRaYwsxdozMvTDHRlaGNcHRCIIgTDyxdMso4D5gj9b6R353/Rm42Xf7ZuDJ6MOLDzNL7FiUlGQEQUgfYnHQugC4CdiplNrmO3YH8F/Ao0qpW4EG4P2xhRg7WRlWZhTnSElGEIS0IWpx11q/Aqggd6+N9nknii9evpCCbFuiwxAEQZgU0sb79pqzZiQ6BEEQhEkj5e0HBEEQ0hERd0EQhBRExF0QBCEFEXEXBEFIQUTcBUEQUhARd0EQhBRExF0QBCEFEXEXBEFIQZTXuDHBQSjVB+xLdBwmKQPaEx2ESSTWiUFinRgk1siZrbUOaKubLBOq+7TWKxMdhBmUUnUSa/yRWCcGiXVimAqxSllGEAQhBRFxFwRBSEGSRdzvTXQAESCxTgwS68QgsU4MSR9rUiyoCoIgCPElWTJ3QRAEIY6IuAuCIKQgCRF3pdR6pdQ+pVS9UuqrvmM1SqlNvmOPKKUSvidekDgfUEodVkpt832dleg4AZRS9yulWpVSu/yOlSilnlFKHfD9W5zIGA2CxPrvSqkWv+t6ZSJj9MU0Uym1USm1Wyn1tlLqs77jSXddQ8SajNc1Wym1WSm13Rfrt3zHk1EDgsWalDpwClrrSf0CrMBBYA6QCWwHFgOPAjf4RexuHwAABDpJREFUzrkHuH2yYzMZ5wPA9YmMLUi8FwHLgV1+x/4H+Krv9leB/050nCFi/Xfgi4mObVyclcBy3+18YL/vdyDprmuIWJPxuiogz3fbBmwCzk02DQgTa1LqgP9XIjL3c4B6rfUhrfUo8DBwDXAJ8JjvnAeBaxMQmz/B4kxKtNYvAZ3jDl+D91pCclxTIGisSYfW+pjWeqvvdh+wB5hBEl7XELEmHdpLv+9bm+9Lk3waECrWpCcR4j4DaPL7vtl3rFtr7Rp3LJEEixPgO0qpHUqpHyulsiY/NNNUaK2P+W4fByoSGYwJ/tl3Xe9PhlKHP0qpauBsvJlbUl/XcbFCEl5XpZRVKbUNaAWewfspOdk0ADg9Vq21cV2TWgdkQTVyvgYsAlYBJcBXEhuOObT3c2UyZxx3A3OBs4BjwA8TG85JlFJ5wB+Bz2mte/3vS7brGiDWpLyuWmu31vosoArvp+RFCQ4pKONjVUqdwRTQgUSIewsw0+/7Kt+xIqVUxrhjiSRgnL6Pv1prPQL8Cu8vZrJyQilVCeD7tzXB8QRFa33C90fkAX5JklxXpZQNr1g+pLX+k+9wUl7XQLEm63U10Fp3AxuB80g+DTgFv1jXTwUdSIS4vwnM962MZwI3AH/Ge9Gu951zM/BkAmLzJ2Ccfn/UCm9NcFeI50g0f8Z7LSE5rmlQjOvq4zqS4Lr6fsb3AXu01j/yuyvprmuwWJP0ujqUUkW+2znAZXjXCJJNA4LFundK6EAiVnGBK/Gu5h8Evu47NgfYDNQDfwCyEr3aHCTO54GdeH+Yv8W3kp7oL+D3eD92O/HWK28FSoHngAPAs0BJouMMEetvfNd1B17xrEyCON+Jt+SyA9jm+7oyGa9riFiT8bouA97yxbQL+Dff8WTUgGCxJqUO+H+J/YAgCEIKIguqgiAIKYiIuyAIQgoi4i4IgpCCiLgLgiCkICLugiAIKYiIu5B2KKX6w9xf7e9YafI5H1BKXR/+TEGYHETcBUEQUhARdyFtUUrlKaWeU0ptVUrtVEr5u35mKKUeUkrtUUo9ppSy+x6zQin1olJqi1LqH+MmQAUhaRBxF9KZYeA6rfVyYA3wQ984OcBC4C6tdS3QC3zS593yM7w+3iuA+4HvJCBuQQhLRvhTBCFlUcB3lVIXAR68FrOGfW+T1vpV3+3fAp8B/g6cATzjew+w4rVREISkQ8RdSGduBBzACq21Uyl1BMj23Tfel0PjfTN4W2t93uSFKAjRIWUZIZ0pBFp9wr4GmO133yyllCHiHwJeAfYBDuO4UsqmlFoyqRELgklE3IV05iFgpVJqJ/BhYK/fffuATyml9gDFwN3au93i9cB/K6W243VePH+SYxYEU4grpCAIQgoimbsgCEIKIuIuCIKQgoi4C4IgpCAi7oIgCCmIiLsgCEIKIuIuCIKQgoi4C4IgpCD/H1qIgn8ocIq+AAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "ig = ImageDataGenerator(preprocessing_function=preprocess_img)\n",
    "\n",
    "params_g = dict(\n",
    "    batch_size=batch_size,\n",
    "    # directory=path_data,\n",
    "    # class_mode='other',\n",
    "    x_col='fname',\n",
    "    y_col='label',\n",
    "    target_size=(img_width, img_height),\n",
    "    seed=random_seed)\n",
    "\n",
    "train_g = ig.flow_from_dataframe(\n",
    "    labels_train, path_data_train, **params_g)\n",
    "valid_g = ig.flow_from_dataframe(\n",
    "    labels_valid, path_data_valid, **params_g)\n",
    "labels_train.groupby(by='label').count().plot()\n",
    "labels_valid.groupby(by='label').count().plot()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/op_def_library.py:263: colocate_with (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Colocations handled automatically by placer.\n"
     ]
    }
   ],
   "source": [
    "base_model = ResNet101(\n",
    "    weights='imagenet', include_top=False, input_shape=(img_width, img_height, 3),\n",
    "    backend=keras.backend, layers=keras.layers, models=keras.models, utils=keras.utils)\n",
    "# base_model = InceptionV3(weights=None, include_top=False)\n",
    "# base_model = ResNet50(\n",
    "#     weights='imagenet', include_top=False, input_shape=(img_width, img_height, 3))\n",
    "# 添加全局平均池化层\n",
    "x = base_model.output\n",
    "x = GlobalAveragePooling2D()(x)\n",
    "\n",
    "# 添加一个全连接层\n",
    "# x = Dense(512, activation='relu')(x)\n",
    "x = Dense(128, activation='relu')(x)\n",
    "\n",
    "# 添加一个分类器，假设我们有200个类\n",
    "predictions = Dense(n_classess, activation='softmax')(x)\n",
    "\n",
    "# 构建我们需要训练的完整模型\n",
    "model = Model(inputs=base_model.input, outputs=predictions)\n",
    "# model.summary()\n",
    "# 首先，我们只训练顶部的几层（随机初始化的层）\n",
    "# 锁住所有 InceptionV3 的卷积层\n",
    "# for layer in base_model.layers:\n",
    "#     layer.trainable = False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "# %%\n",
    "ckpt = ModelCheckpoint(\n",
    "    '../tmp/ckpt-exp1-'+time.strftime('%Y-%m-%d_%H_%M')+'-Epoch_{epoch:03d}-acc_{acc:.5f}-val_acc_{val_acc:.5f}.h5', save_best_only=True, monitor='val_acc')\n",
    "estop = EarlyStopping(monitor='val_acc', min_delta=1e-7,\n",
    "                      verbose=1, patience=20)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/math_ops.py:3066: to_int32 (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Use tf.cast instead.\n",
      "Epoch 1/100\n",
      "7500/7500 [==============================] - 2686s 358ms/step - loss: 0.4392 - acc: 0.8687 - val_loss: 0.7921 - val_acc: 0.8061\n",
      "Epoch 2/100\n",
      "3871/7500 [==============>...............] - ETA: 21:27 - loss: 0.1337 - acc: 0.9568"
     ]
    }
   ],
   "source": [
    "model.compile(optimizer=Adam(lr=1e-4), loss='categorical_crossentropy',\n",
    "              metrics=['accuracy'])\n",
    "model.fit_generator(\n",
    "    train_g,\n",
    "    # steps_per_epoch=100,\n",
    "    steps_per_epoch=train_g.n // batch_size,\n",
    "    epochs=100,\n",
    "    callbacks=[ckpt, estop],\n",
    "    validation_data=valid_g,\n",
    "    # validation_steps=1,\n",
    "    validation_steps=valid_g.n // batch_size\n",
    ")\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
